﻿namespace Resonator.Tests.Models
{
	using System.Collections.Generic;
	using NUnit.Framework;
	using Resonator.Core.Services;
	using Resonator.Domain.Models;
	using Resonator.Domain.Services;

	[TestFixture]
	[Category("Database")]
	public class ResourceTester : ModelTester
	{
		private IRepository<Resource> _resourceRepository;

		[SetUp]
		public override void SetUp()
		{
			base.SetUp();

			_resourceRepository = new Repository<Resource>();
			_resourceRepository.DeleteAll();
			_resourceRepository.PurgeAll();
			_resourceRepository.Optimize();

			IRepository<Translation> translationRepository = new Repository<Translation>();
			translationRepository.DeleteAll();
			translationRepository.PurgeAll();
			translationRepository.Optimize();
		}

		[Test]
		public void Can_Add_Translation_To_Existing_Resource()
		{
			Resource resource = new Resource();
			resource.Phrase = "Yes";
			_resourceRepository.Save( resource ); 

			Resource resourceToUpdate = _resourceRepository.Find( resource.Id );
			Translation translation = new Translation();
			translation.Phrase = "Si";
			resourceToUpdate.AddTranslation( translation );
			_resourceRepository.Save( resourceToUpdate );

			Resource resourceFromDb = _resourceRepository.Find( resourceToUpdate.Id );

			Assert.IsNotNull( resourceFromDb );
			Assert.Greater( resourceFromDb.Translations.Count, 0 );
			Assert.IsTrue( resourceFromDb.Translations.Contains( translation ) );
		}

		[Test]
		public void Can_Create_And_Save_Resource()
		{
			Resource resource = new Resource();
			resource.Name = "Name";
			resource.Phrase = "Yes";
			resource.Context = "Used as confirmation link or button text";

			_resourceRepository.Save( resource ); 

			Assert.AreNotEqual( 0, resource.Id );

			Resource resourceFromDb = _resourceRepository.Find( resource.Id );

			Assert.IsNotNull( resourceFromDb );
			Assert.AreEqual( resource.Phrase, resourceFromDb.Phrase );
			Assert.AreEqual( resource.Context, resourceFromDb.Context );
		}

		[Test]
		public void Can_Create_And_Save_Resource_With_Translation()
		{
			Resource resource = new Resource();
			resource.Phrase = "Yes";

			Translation translation = new Translation();
			translation.Phrase = "Sí";

			resource.AddTranslation( translation );

			_resourceRepository.Save( resource ); 

			Assert.AreNotEqual( 0, resource.Id );
			Assert.AreNotEqual( 0, translation.Id );

			using( _resourceRepository.CreateSessionScope() )
			{
				Resource resourceFromDb = _resourceRepository.Find( resource.Id ); 

				Assert.IsNotNull( resourceFromDb );
				Assert.AreEqual( resource.Phrase, resourceFromDb.Phrase );
				Assert.Greater( resource.Translations.Count, 0 );
				Assert.IsTrue( resource.Translations.Contains( translation ) );
			}
		}

		[Test]
		public void Can_Query_Resource()
		{
			Resource resource = new Resource();
			resource.Phrase = "Yes";
			resource.Context = "Used as confirmation link or button text";

			using(_resourceRepository.CreateSessionScope())
			{
				_resourceRepository.Save(resource); 
			}

			IList<Resource> resources = _resourceRepository.Search( "Yes" ); 

			Assert.AreEqual( 1, resources.Count );

			Assert.AreEqual( resource.Id, resources[0].Id );
			Assert.AreEqual( resource.Phrase, resources[0].Phrase );
			Assert.AreEqual( resource.Context, resources[0].Context );
		}

		[Test]
		public void Can_Query_Resource_By_Translation()
		{
			Resource resource = new Resource();
			resource.Phrase = "Yes";

			Translation translation = new Translation();
			translation.Phrase = "是";
			translation.LCID = 2052;
			resource.AddTranslation( translation );

			using (_resourceRepository.CreateSessionScope())
			{
				_resourceRepository.Save(resource);
			}

			IList<Resource> resources = _resourceRepository.Search( "是" );

			Assert.AreEqual( 1, resources.Count );
			Assert.AreEqual( resource.Id, resources[0].Id );
			Assert.AreEqual( resource.Phrase, resources[0].Phrase );
			Assert.AreEqual( resource.Context, resources[0].Context );

			resources = _resourceRepository.Search("Chinese");
			Assert.AreEqual( 1, resources.Count );

			resources = _resourceRepository.Search("CHS");
			Assert.AreEqual( 1, resources.Count );

			resources = _resourceRepository.Search("Yes AND zh-CN");
			Assert.AreEqual( 1, resources.Count );

			resources = _resourceRepository.Search("Yes AND es-MX");
			Assert.AreEqual( 0, resources.Count );
		}

		[Test]
		public void Can_Updated_Existing_Resource()
		{
			Resource resource = new Resource();
			resource.Phrase = "Yes";
			_resourceRepository.Save( resource );

			Resource resourceToUpdate = _resourceRepository.Find( resource.Id ); 
			resourceToUpdate.Phrase = "No";
			_resourceRepository.Save( resourceToUpdate );

			Resource resourceFromDb = _resourceRepository.Find( resourceToUpdate.Id );

			Assert.IsNotNull( resourceFromDb );
			Assert.AreEqual( "No", resourceFromDb.Phrase );
		}
	}
}